/*
 * fat32.c
 *
 *  Created on: 25/10/2011
 *      Author: utn_so
 */

#include "fat32.h"
#include "mixed_headers.h"

/*******************************************************************/
/*	Variables Globales	*/

extern pthread_mutex_t mutex_asin_arch_disco;
extern pthread_mutex_t mutex_fat;

extern FILE* archivoDisco;

/*******************************************************************/

/*	recibe el sector inicial del cluster pedido	*/
int32_t traerCluster(struct bootSector* boot, int32_t sectorIni, unsigned char* cluster)
{

	uint32_t aux1;
	/*	Posiciono al archivo en el byte correspondiente	*/
	/* estoy pidiendo el boot sector, no tengo la estructura todavia	*/
	if(sectorIni != 0)
		aux1 = sectorIni * boot -> BPB_BytsPerSec;
	else
		aux1 = 0;

	int32_t largoCluster;
	int32_t i;
	/* estoy pidiendo el boot sector, no tengo la estructura todavia	*/
	if(sectorIni != 0)
		largoCluster = boot -> BPB_BytsPerSec * boot -> BPB_SecPerClus;
	else
		largoCluster = 512 * 8;

	pthread_mutex_lock(&mutex_asin_arch_disco);
	fseek(archivoDisco, aux1, SEEK_SET);

	for(i=0; i<largoCluster; i++)
		cluster[i] = fgetc(archivoDisco);

	pthread_mutex_unlock(&mutex_asin_arch_disco);

	return 0;

}

uint32_t firstDataSector(struct bootSector* bootSector)
{
	/*	FAT32	*/
	/*	FAT32	*/
	/*	FAT32	*/

	uint32_t firstDataSector = bootSector-> BPB_RsvdSecCnt +
			( bootSector -> BPB_NumFATs * bootSector -> BPB_FATSz32) /*+ RootDirSectors*/;

	return firstDataSector;
}

uint32_t firstSectorofCluster(struct bootSector* bootSector, uint32_t cluster)
{
	/*	FAT32	*/
	/*	FAT32	*/
	/*	FAT32	*/

	uint32_t firstData = firstDataSector(bootSector);

	uint32_t FirstSectorofCluster = ((cluster - 2) * bootSector -> BPB_SecPerClus) + firstData;

	return FirstSectorofCluster;

}

uint32_t totalDataSec(struct bootSector* bootSector)
{
	/*	FAT32	*/
	/*	FAT32	*/
	/*	FAT32	*/

	uint32_t firstData = firstDataSector(bootSector);

	uint32_t DataSec = bootSector -> BPB_TotSec32 - firstData;

	return DataSec;

}

uint32_t cantidadClustersData(struct bootSector* boot)
{
	uint32_t dataClusters = totalDataSec(boot);

	dataClusters /= boot -> BPB_SecPerClus;

	return dataClusters;
}

uint32_t proximaEntryDir(struct DirStruct* directorio)
{
	uint32_t proxCluster;
	char* auxChar = malloc(sizeof(char)*20);

	strcpy(auxChar, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(auxChar, hexToChar(valorHighChar(directorio -> DIR_FstClusHI[1])));
	strcat(auxChar, hexToChar(valorLowChar(directorio -> DIR_FstClusHI[1])));
	strcat(auxChar, hexToChar(valorHighChar(directorio -> DIR_FstClusHI[0])));
	strcat(auxChar, hexToChar(valorLowChar(directorio -> DIR_FstClusHI[0])));

	strcat(auxChar, hexToChar(valorHighChar(directorio->DIR_FstClusLO[1])));
	strcat(auxChar, hexToChar(valorLowChar(directorio->DIR_FstClusLO[1])));
	strcat(auxChar, hexToChar(valorHighChar(directorio->DIR_FstClusLO[0])));
	strcat(auxChar, hexToChar(valorLowChar(directorio->DIR_FstClusLO[0])));

	/*printf("%s\n", auxChar);*/
	/*	lo doy vuelta arriba, es mas simple, son dos bytes invertidos*/
	/*proxCluster = swap_uint32(htoi(auxChar));*/
	proxCluster = htoi(auxChar);
	free(auxChar);
	return proxCluster;
}

uint32_t tirateUnLS(ListaDirectorios* recorriendo)
{

	while(1)
		{
		if(recorriendo -> nombreLargo != NULL)
			printf("%s\n", recorriendo -> nombreLargo);

		else
			printfDirectorio(recorriendo -> directorio);

		recorriendo = (ListaDirectorios*)recorriendo -> siguiente;

		if(recorriendo -> siguiente == NULL)
			{
			if(recorriendo -> nombreLargo != NULL)
				printf("%s\n", recorriendo -> nombreLargo);

			else
				printfDirectorio(recorriendo -> directorio);
			break;
			}
		}

	return 0;
}

uint32_t printfDirectorio(struct DirStruct* directorio)
{

	char* nombre = malloc(sizeof(char)*20);

	if(directorio ->DIR_Name[0] != 0x2E)
		{
		traerNombreShort(directorio, nombre);
		printf("%s\n", nombre);
		}

	else
		{
		printf(".");
		if(directorio ->DIR_Name[1] == 0x2E)
			printf(".");
		printf("\n");
		}

	free(nombre);
	return 0;
}

int32_t traerNombreShort(struct DirStruct* directorio, char* nombre)
{
	//char* nombre = malloc(sizeof(char)*12);
	uint32_t i;
	uint32_t x=0;

	if(directorio -> DIR_Name[0] == DOT_DotDot)
		{
		nombre[0] = 0x2E;
		x++;
			if(directorio -> DIR_Name[1] == DOT_DotDot)
				{
				nombre[1] = 0x2E;
				x++;
				}
		}
	else
		{
			for(i=0; i<11; i++)
			{
			if(directorio -> DIR_Name[i] != ESPACIO_SHORT_NAME)
				{
				nombre[x] = directorio -> DIR_Name[i];
				x++;
				}

			if((i==7) && (directorio -> DIR_Attr == ATTR_ARCHIVE))
				{
				nombre[x] = '.';
				x++;
				}
			}
		}

	nombre[x]='\0';
	return 0;
}

/*	Poderosisima funcion, si el path es valido devuelve en la estructura que se le pasa como parametro
 * 	el archivo/directorio buscado, y hace un return del cluster donde se encuentra el archivo 			*/
int32_t verificarPath(struct bootSector* boot, const char* path, ListaDirectorios* directorioFound)
{

	//char tokens[2] = "/";
	char *ptr;//=malloc(25);
	char *ptr2;
	char* pathAux = malloc(sizeof(char)*30);
	strcpy(pathAux, path);
	int32_t seEncontro = 0;

	//	movimientos que se van haciendo
	int32_t indiceMovimiento = 0;
	int32_t *listaClustersMoviemiento = malloc(sizeof(int32_t)* CANTIDAD_MAX_MOVIEMIENTOS);
	listaClustersMoviemiento[indiceMovimiento] = boot -> BPB_RootClus;
	int32_t retorno;

	int32_t tengoDOTDOT = 0;
	int32_t estoyNavegando = 0;
	int32_t posibleSalidaDOTDOT = 0;

	//	recorriendo el directorio
	ListaDirectorios* firstDir = NULL;
	ListaDirectorios* lastDir = NULL;
	ListaDirectorios* recorriendo = NULL;

	ListaDirectorios* entAnt = malloc(sizeof(ListaDirectorios));
	entAnt -> directorio = malloc(sizeof(struct DirStruct));
	entAnt -> nombreLargo = malloc(sizeof(char)* 20);

	//	el kernel pide el root de esta manera
	if(strcmp("/", pathAux) == 0)
		strcpy(pathAux, "./");

	ptr = strtok_r(pathAux,"/",&ptr2);//(pathAux, "/");

	while( ptr != NULL )
		{

		//printf("Entrada: %s\n", ptr );

		//	The dot entry is a directory that points to itself
		if( !strcmp(ptr, ".") )
			/*	en la variable directorioClusterACTUAL se encuentra el cluster del dir en ese momento
			 * 	siempre se arranca en 2, root cluster
			 * 	No hace falta modificar nada, ya lo tengo
			 * 	guardado en la lista de movimientos			*/
			seEncontro = 1;

		//	the dotdot entry points to the starting cluster of the parent of this directory
		else if( !strcmp(ptr, "..") )
			/*	en la variable directorioClusterANTERIOR se encuentra el cluster del dir anterior
			 * 	siempre se arranca en 2, root cluster	*/
			{
			seEncontro = 1;
			tengoDOTDOT = 1;
			}

		else
			{
			//	antes de pedir nuevos me guardo el anterior
			/*if(recorriendo != NULL)
				{
				//entAnt -> clusters = recorriendo -> clusters;
				*entAnt -> directorio = *recorriendo -> directorio;
				*entAnt -> nombreLargo = *recorriendo -> nombreLargo;
				//entAnt -> directorio = recorriendo -> directorio;
				//entAnt -> nombreLargo = recorriendo -> nombreLargo;
				entAnt -> posicionEntrada = recorriendo -> posicionEntrada;
				entAnt -> parentCluster = recorriendo -> parentCluster;
				//	no me interesa el siguiente
				entAnt -> siguiente = NULL;
				}*/

			if(firstDir != NULL)
				liberarListaDirectorio(firstDir);

			firstDir = malloc(sizeof(ListaDirectorios));
			firstDir -> directorio = NULL;
			firstDir -> siguiente = NULL;
			firstDir -> clusters = NULL;
			firstDir -> nombreLargo = NULL;

			lastDir = NULL;
			leerFAT32DirectoryEntries(boot, listaClustersMoviemiento[indiceMovimiento], firstDir, lastDir);

			recorriendo = firstDir;

			if(recorriendo -> directorio != NULL)
				{
				while(1)
					{
					//	Puede ser . o ..
					if(recorriendo -> nombreLargo != NULL)
						{
						if(strcmp(recorriendo -> nombreLargo, ptr) == 0)
							{seEncontro = 1; estoyNavegando = 1; break;}
						}

					else
						{
						char* nombre = malloc(sizeof(char)*20);
						traerNombreShort(recorriendo -> directorio, nombre);
						if(strcmp(nombre,ptr) == 0)
							{seEncontro = 1; estoyNavegando = 1; free(nombre); break;}
						free(nombre);
						}

					if((recorriendo -> siguiente != NULL))
						{
						recorriendo = (ListaDirectorios*)firstDir -> siguiente;
						liberarDirectorio(firstDir);
						firstDir = recorriendo;
						}

					else
						{seEncontro = 0; break;}
					}
				}
			//directorio vacio, solo pasa en el root, no hay . ni ..
			else
				seEncontro = 0;
			}

		//	No existe esa entrada, salgo del bucle principal
		if(!seEncontro)
			break;

		//	tratamiento de la entrada
		posibleSalidaDOTDOT = 0;
		/*	salto al proximo directorio	*/
		if(tengoDOTDOT)
			{
			indiceMovimiento--;

			/*	vuelvo para atras	*/
			if(indiceMovimiento < 0)
				indiceMovimiento = 0;

			tengoDOTDOT = 0;
			posibleSalidaDOTDOT = 1;
			}

		if(estoyNavegando)
			{
			indiceMovimiento++;
			listaClustersMoviemiento[indiceMovimiento] = proximaEntryDir(recorriendo -> directorio);
			estoyNavegando = 0;
			}

		ptr = strtok_r(NULL, "/",&ptr2);
		}

	if(seEncontro)
		{
		if(posibleSalidaDOTDOT && (listaClustersMoviemiento[indiceMovimiento] == boot ->BPB_RootClus))
			{
			directorioFound -> directorio  = NULL;
			liberarListaDirectorio(firstDir);
			liberarDirectorio(entAnt);
			retorno = listaClustersMoviemiento[indiceMovimiento];
			free(pathAux);
			free(listaClustersMoviemiento);
			return retorno;
			}

		/*	pierdo la referencia	*/
		else if(recorriendo != NULL)
			{
			if(posibleSalidaDOTDOT)
				{
				directorioFound -> directorio = malloc(sizeof(struct DirStruct));
				*directorioFound -> directorio = *entAnt -> directorio;
				directorioFound -> nombreLargo = malloc(sizeof(char)* 20);
				*directorioFound -> nombreLargo = *entAnt -> nombreLargo;
				directorioFound -> posicionEntrada = entAnt -> posicionEntrada;
				directorioFound -> parentCluster = entAnt -> parentCluster;
				}

			else
				{
				directorioFound -> directorio = malloc(sizeof(struct DirStruct));
				*directorioFound -> directorio = *recorriendo -> directorio;
				directorioFound -> nombreLargo = malloc(sizeof(char)* 20);
				*directorioFound -> nombreLargo = *recorriendo -> nombreLargo;
				directorioFound -> posicionEntrada = recorriendo -> posicionEntrada;
				directorioFound -> parentCluster = recorriendo -> parentCluster;
				}

			/*	no me interesa el siguiente	*/
			directorioFound -> siguiente = NULL;
			}
		}
	else
		{
		/*	path incorrecto	*/
		liberarListaDirectorio(firstDir);
		liberarDirectorio(entAnt);
		free(pathAux);
		free(listaClustersMoviemiento);
		return -1;
		}

	liberarListaDirectorio(firstDir);
	liberarDirectorio(entAnt);
	retorno = listaClustersMoviemiento[indiceMovimiento];
	free(ptr);
	free(pathAux);
	free(listaClustersMoviemiento);
	/*	devuelvo el cluster del repositorio/archivo	*/
	return retorno;

}

int32_t leerFAT32DirectoryEntries(struct bootSector* bootSector, uint32_t cluster,
				ListaDirectorios* firstDir,ListaDirectorios* lastDir)
{

	//	puede o no tener entrada con LFN
	int8_t hayLONGNAME = 0;
	char *cadenaEnUTF16;
	char *cadenaEnUTF8;
	size_t tamanioDeCadenaEnUTF16;
	size_t tamanioDeCadenaEnUTF8;
	unsigned char checkSumLFNAnt;

	uint32_t sector = firstSectorofCluster(bootSector, cluster);

	unsigned char* bufferStruct =  malloc(sizeof(char)* bootSector ->BPB_BytsPerSec * bootSector ->BPB_SecPerClus);
	traerCluster(bootSector, sector, bufferStruct);

	int i;

					/*	16 entradas por sector(32 bytes cada entrada), 8 sectores	*/
	int largoCluster = LARGO_STRUCT_DIRECTORY * 16 * bootSector -> BPB_SecPerClus;

	unsigned char* bufferStructDir = malloc(sizeof(char)*LARGO_STRUCT_DIRECTORY);

	i=0;
	uint32_t contador;

	while((bufferStruct[i] != DIR_Name_POWER_FREE) && (i<largoCluster))
		{

		for(contador = 0; contador<LARGO_STRUCT_DIRECTORY; contador++)
			bufferStructDir[contador]= bufferStruct[i+contador];

		/*	******************************************************************************
		 * 	DIRECTORY																	*/
		if(((bufferStruct[i+11] & ATTR_DIRECTORY) == ATTR_DIRECTORY) && (bufferStruct[i] != DIR_Name_FREE))
			{
			ListaDirectorios* nuevoDir;
			struct DirStruct* dir = malloc(sizeof(struct DirStruct));

			if(firstDir -> directorio == NULL)
				{
				firstDir -> directorio = dir;
				nuevoDir = firstDir;
				lastDir = firstDir;
				interpretarEntradaDirectorioArchivo(firstDir -> directorio, bufferStructDir);
				}

			else
				{
				nuevoDir = malloc(sizeof(ListaDirectorios));
				nuevoDir -> siguiente = NULL;
				nuevoDir -> clusters = NULL;
				nuevoDir -> nombreLargo = NULL;
				lastDir -> siguiente = (struct ListaDirectorios*) nuevoDir;
				lastDir = nuevoDir;
				nuevoDir -> directorio = dir;
				interpretarEntradaDirectorioArchivo(nuevoDir -> directorio, bufferStructDir);
				}

			/*printf("EOC para directorio: %02x\n",leerEntradaFAT( bootSector, proximaEntryDir(dir)) );*/

			if(hayLONGNAME)
				{
				if(checkSumLFNAnt == ChkSum(dir->DIR_Name))
					{
					nuevoDir -> nombreLargo = malloc(sizeof(char)*20);
					strcpy(nuevoDir -> nombreLargo,cadenaEnUTF8);
					free(cadenaEnUTF8);
					}
				else
					nuevoDir -> nombreLargo = NULL;
				}
			else
				nuevoDir -> nombreLargo = NULL;

			/*	guardo la posicion, facilito cuando hago cambios	*/
			nuevoDir -> parentCluster = cluster;
			nuevoDir -> posicionEntrada = i;

			/*	Lo borro siempre	*/
			hayLONGNAME = 0;
			}

		/*	******************************************************************************
		 * 	ARCHIVE																		*/
		else if(((bufferStruct[i+11] & ATTR_ARCHIVE)== ATTR_ARCHIVE) && (bufferStruct[i] != DIR_Name_FREE))
			{
			ListaDirectorios* nuevoDir;
			struct DirStruct* dir = malloc(sizeof(struct DirStruct));

			if(firstDir -> directorio == NULL)
				{
				firstDir -> directorio = dir;
				nuevoDir = firstDir;
				lastDir = firstDir;
				interpretarEntradaDirectorioArchivo(firstDir -> directorio, bufferStructDir);
				}

			else
				{
				nuevoDir = malloc(sizeof(ListaDirectorios));
				nuevoDir -> siguiente = NULL;
				nuevoDir -> clusters = NULL;
				lastDir -> siguiente = (struct ListaDirectorios*) nuevoDir;
				lastDir = nuevoDir;
				nuevoDir -> directorio = dir;
				interpretarEntradaDirectorioArchivo(nuevoDir -> directorio, bufferStructDir);
				}

			/*printf("EOC para archivo: %i\n",leerEntradaFAT( bootSector, proximaEntryDir(nuevoDir -> directorio)) );*/

			if(hayLONGNAME)
				{
				if(checkSumLFNAnt == ChkSum(dir->DIR_Name))
					{
					nuevoDir -> nombreLargo = malloc(sizeof(char)*20);
					strcpy(nuevoDir -> nombreLargo,cadenaEnUTF8);
					free(cadenaEnUTF8);
					}
				else
					nuevoDir -> nombreLargo = NULL;
				}
			else
				nuevoDir -> nombreLargo = NULL;

			/*	guardo la posicion, facilito cuando hago cambios	*/
			nuevoDir -> parentCluster = cluster;
			nuevoDir -> posicionEntrada = i;

			/*	Lo borro siempre	*/
			hayLONGNAME = 0;
			}

		/*	******************************************************************************
		 * 	LONG_NAME																	*/
		else if(	(bufferStruct[i+11] == (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID))
							&&	(bufferStruct[i]!=DIR_Name_FREE) && (bufferStruct[i] == 0x41) 		)

			/*	Condiciones: 	que el atributo sea de una entrada LFN
			 * 					que la entrada no tenga al comienzo de un dir vacio
			 * 					que la entrada sea igual a una sola LFN, no hay mas de una LFN concatenada
			 *
			 * 					Puede optimizarse la condicion, pero es mas comprensible de esta manera				*/
			{
			hayLONGNAME = 1;

			struct LongDirStruct* entradaLFN = malloc(sizeof(struct LongDirStruct));
			interpretarEntradaLFN(entradaLFN, bufferStructDir);

			cadenaEnUTF16 = malloc(sizeof(char)*30);
			cadenaEnUTF8 = malloc(sizeof(char)*20);

			/*	check sum	*/
			checkSumLFNAnt = entradaLFN -> LDIR_Chksum;

			/*	paso el long name al buffer */

			/*LDIR_Name1[10]*/
			for(contador = 0; contador<10; contador++)
				cadenaEnUTF16[contador] = entradaLFN -> LDIR_Name1[contador];

			/*LDIR_Name2[12]*/
			for(contador = 0; contador<12; contador++)
				cadenaEnUTF16[contador+10] = entradaLFN -> LDIR_Name2[contador];

			/*LDIR_Name3[4]*/
			for(contador = 0; contador<4; contador++)
				cadenaEnUTF16[contador+22] = entradaLFN -> LDIR_Name3[contador];

			//tamanioDeCadenaEnUTF16 = 26;
			tamanioDeCadenaEnUTF16 = 13;
			tamanioDeCadenaEnUTF8 = 0;

			unicode_utf16_to_utf8_inbuffer((const uint16_t *)cadenaEnUTF16, tamanioDeCadenaEnUTF16, cadenaEnUTF8, &tamanioDeCadenaEnUTF8);

			/*printf("Entrada Long Name: ");
			for(contador=0; contador<14; contador++)
				printf("%c", cadenaEnUTF8[contador]);
			printf("\n");*/

			free(cadenaEnUTF16);
			free(entradaLFN);
			}

		/*if(bufferStruct[i+11] == (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID
									| ATTR_DIRECTORY | ATTR_ARCHIVE ))
			{
				printf("apa!\n");

			}*/


		/*	Entrada libre, si no entra en ningun if sigue, no hay que hacer nada	*/
		/* if(bufferStruct[i] == DIR_Name_FREE)
			{}*/

			/*	Voy a la siguiente entrada	*/

		i+=32;
		if(i>=largoCluster)
			break;

		}

	free(bufferStruct);
	free(bufferStructDir);

	if(verificarUltimoClusterCadena(bootSector, cluster) == -1)
		/*	No termino el root directory, es mas largo que un cluster	*/
		leerFAT32DirectoryEntries(bootSector, leerEntradaFAT(bootSector, cluster), firstDir, lastDir);

	return 0;
}


int32_t liberarListaDirectorio(ListaDirectorios* ini)
{

	//	lista vacia
	if(ini == NULL)
		return 0;

	ListaDirectorios* pasaje;

	while(1)
		{
		if(ini -> siguiente == NULL)
			{
			liberarDirectorio(ini);
			break;
			}

		else
			{
			pasaje = (ListaDirectorios*)ini -> siguiente;
			liberarDirectorio(ini);
			ini = pasaje;
			}
		}

	return 0;

}

int32_t liberarDirectorio(ListaDirectorios* ldir)
{
	//	libero los que alloco
	if(ldir->nombreLargo!= NULL)
		free(ldir->nombreLargo);
	if(ldir->directorio!= NULL)
		free(ldir->directorio);

	free(ldir);
	return 0;
}

/*-----------------------------------------------------------------------------
 *	ChkSum()
 *	Returns an unsigned byte checksum computed on an unsigned byte
 *	array.  The array must be 11 bytes long and is assumed to contain
 *	a name stored in the format of a MS-DOS directory entry.
 *	Passed:	 pFcbName    Pointer to an unsigned byte array assumed to be
 *                          11 bytes long.
 *	Returns: Sum         An 8-bit unsigned checksum of the array pointed
 *                           to by pFcbName.
 *------------------------------------------------------------------------------	*/
unsigned char ChkSum (unsigned char *pFcbName)
{
	short FcbNameLen;
	unsigned char Sum;

	Sum = 0;
	for (FcbNameLen=11; FcbNameLen!=0; FcbNameLen--) {
		/*	NOTE: The operation is an unsigned char rotate right	*/
		Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pFcbName++;
	}
	return (Sum);
}

char* stringToUpper(char* cadena)
{
	int32_t i;
	for(i = 0; cadena[i]; i++)
		cadena[i] = toupper(cadena[i]);

	return cadena;
}

char* stringToLower(char* cadena)
{
	int32_t i;
	for(i = 0; cadena[i]; i++)
		cadena[i] = tolower(cadena[i]);

	return cadena;
}

uint32_t dameClusterSegunOffset(struct bootSector* boot, int32_t offset)
{

	int32_t bytesTotales = boot ->BPB_BytsPerSec * boot -> BPB_SecPerClus;

	uint32_t cluster = offset / bytesTotales;

	return cluster;
}

int32_t verificarNombreDistinto(ListaDirectorios* firstDir, char* nombreArchivo)
{

	if( firstDir -> directorio == NULL)
		{
		/*	directorio vacio	*/
		free(firstDir);
		return 0;
		}

	ListaDirectorios* pasaje;

	while(1)
		{
		if(firstDir ->nombreLargo == NULL)
			{
			char* nombre = malloc(sizeof(char)*20);
			traerNombreShort(firstDir -> directorio, nombre);
			if(strcmp(nombre, nombreArchivo) == 0)
				{free(nombre); liberarListaDirectorio(firstDir); return -1;}
			free(nombre);
			}

		else
			{
			if(strcmp(firstDir -> nombreLargo, nombreArchivo) == 0)
				{liberarListaDirectorio(firstDir); return -1;}
			}

		if(firstDir-> siguiente != NULL)
			{
			pasaje =(ListaDirectorios*) firstDir -> siguiente;
			liberarDirectorio(firstDir);
			firstDir = pasaje;
			}

		/*	no hay entradas con ese nombre	*/
		else
			{
			liberarDirectorio(firstDir);
			return 0;
			}

		}

	return 0;
}

int32_t crearEntradaDIR(struct bootSector* boot, char* nombre, struct DirStruct* dir, int32_t modo)
{

	char* nombreAux = malloc(sizeof(char)*30);
	strcpy(nombreAux, nombre);
	char* nombreToUpper = stringToUpper(nombreAux);
	int32_t i;

	/*	ARCHIVO	*/
	if(modo == ARCHIVO)
		{
		char* nombre2;
		char* exten;
		char tokens[2] = ".";
		nombre2 = strtok(nombreToUpper, tokens);
		exten = strtok(NULL, tokens);
		/*printf("Nombre Archivo: %s\n", nombre);
		printf("Extension de Archivo: %s\n", exten);*/

		/*	Extension	*/
		dir -> DIR_Name[8] = exten[0];
		dir -> DIR_Name[9] = exten[1];
		dir -> DIR_Name[10] = exten[2];

		/*	Nombre	*/
		int32_t largo = strlen(nombre2);
		if(largo <= 8)
			{
			if(largo == 8)
				{
				for(i=0; i<8; i++)
					dir -> DIR_Name[i] = nombre2[i];
				}

			else
				{
				for(i=0; i<largo; i++)
					dir -> DIR_Name[i] = nombre2[i];

				/*	formato DOS	*/
				for(i=largo; i<8; i++)
					dir -> DIR_Name[i] = ESPACIO_SHORT_NAME;

				}
			}

		else
			{
			for(i=0; i<6; i++)
				dir -> DIR_Name[i] = nombre2[i];

			dir -> DIR_Name[6] = SHORT_NAME_WITH_LFN_SIGNAL_1;
			dir -> DIR_Name[7] = SHORT_NAME_WITH_LFN_SIGNAL_2;
			}

		dir -> DIR_Attr = ATTR_ARCHIVE;

		/*	Proximo cluster 0, archivo vacio	*/
		dir -> DIR_FstClusHI[0] = 0x00;
		dir -> DIR_FstClusHI[1] = 0x00;
		dir -> DIR_FstClusLO[0] = 0x00;
		dir -> DIR_FstClusLO[1] = 0x00;
		}

	/*	DIRECTORIO	*/
	else
		{
		/*	Nombre	*/
		int32_t largo = strlen(nombreToUpper);
		if(largo <= 8)
			{
			if(largo == 8)
				{
				for(i=0; i<8; i++)
					dir -> DIR_Name[i] = nombreToUpper[i];
				}

			else
				{
				for(i=0; i<largo; i++)
					dir -> DIR_Name[i] = nombreToUpper[i];

				/*	formato DOS	*/
				for(i=largo; i<8; i++)
					dir -> DIR_Name[i] = ESPACIO_SHORT_NAME;

				}
			}

		else
			{
			for(i=0; i<6; i++)
				dir -> DIR_Name[i] = nombreToUpper[i];

			dir -> DIR_Name[6] = SHORT_NAME_WITH_LFN_SIGNAL_1;
			dir -> DIR_Name[7] = SHORT_NAME_WITH_LFN_SIGNAL_2;
			}

			/*	directorio sin extencion	*/
			dir -> DIR_Name[8] = ESPACIO_SHORT_NAME;
			dir -> DIR_Name[9] = ESPACIO_SHORT_NAME;
			dir -> DIR_Name[10] = ESPACIO_SHORT_NAME;

			dir -> DIR_Attr = ATTR_DIRECTORY;
		}

	/*	Sea archivo o directorio, su file size es 0 cuando se crea	*/

	dir -> DIR_FileSizePOSTA[0] = 0x00;
	dir -> DIR_FileSizePOSTA[1] = 0x00;
	dir -> DIR_FileSizePOSTA[2] = 0x00;
	dir -> DIR_FileSizePOSTA[3] = 0x00;

	free(nombreAux);
	return 0;

}

int32_t crearEntradaLFN(char* nombre, struct DirStruct* dir, struct LongDirStruct* lfn)
{

	char *cadenaEnUTF16;
	char *cadenaEnUTF8;
	size_t tamanioDeCadenaEnUTF16;
	size_t tamanioDeCadenaEnUTF8;

	int32_t largo = strlen(nombre);

	/*	primera y unica	*/
	lfn -> LDIR_Ord = 0x41;

	lfn -> LDIR_Attr = ATTR_LONG_NAME;

	lfn -> LDIR_Chksum = ChkSum (dir -> DIR_Name);

	lfn -> LDIR_FstClusLO[0] = 0x00;
	lfn -> LDIR_FstClusLO[1] = 0x00;

	/*	PASAJE PRUEBA UTF8 - UTF16	*/
	cadenaEnUTF16 = malloc(sizeof(char)*25);
	cadenaEnUTF8 = malloc(sizeof(char)*20);
	strcpy(cadenaEnUTF8, nombre);
	tamanioDeCadenaEnUTF8 = largo;
	tamanioDeCadenaEnUTF16 = 0;

	unicode_utf8_to_utf16_inbuffer(cadenaEnUTF8, tamanioDeCadenaEnUTF8,(uint16_t *)cadenaEnUTF16, &tamanioDeCadenaEnUTF16);

	free(cadenaEnUTF8);
	/*printf("%s", cadenaEnUTF16);*/

	/*	PASAJE PRUEBA UTF16 - UTF8	*/
	/*tamanioDeCadenaEnUTF8 = 0;
	tamanioDeCadenaEnUTF16 = 26;
	unicode_utf16_to_utf8_inbuffer(cadenaEnUTF16, tamanioDeCadenaEnUTF16, cadenaEnUTF8, &tamanioDeCadenaEnUTF8);
	printf("%s\n", cadenaEnUTF8);*/

	/* llenar con el nombre, 0x0000 y 0xFFFF */
	int32_t largoNombreLFN = largo * 2;
	int32_t i;

	unsigned char* bufferLFN = malloc(sizeof(char)*26);

	/*	relleno con 0xffff*/
	for(i=0; i<26; i++)
		bufferLFN[i] = 0xff;

	for(i=0; i<largoNombreLFN; i++)
		bufferLFN[i] = cadenaEnUTF16[i];

	free(cadenaEnUTF16);

	if(largoNombreLFN<=24)
	bufferLFN[largoNombreLFN] = 0x00;
	bufferLFN[largoNombreLFN+1] = 0x00;

	/*printf("Buffer LFN: ");
	for(i=0; i<26; i++)
		printf("%02x", bufferLFN[i]);*/

	/*	paso a la estructura	*/
	for(i=0; i<10; i++)
		lfn -> LDIR_Name1[i] = bufferLFN[i];

	for(i=0; i<12; i++)
		lfn -> LDIR_Name2[i] = bufferLFN[i+10];

	for(i=0; i<4; i++ )
		lfn -> LDIR_Name3[i] = bufferLFN[i+22];

	free(bufferLFN);
	return 0;

}

int32_t crearEntradaCluster(struct bootSector* boot, uint32_t cluster, struct DirStruct* dir,
							struct LongDirStruct* lfn)
{

	int32_t primerSector = firstSectorofCluster(boot, cluster);
	/*	pido el cluster en base al primer sector	*/
	unsigned char* clusterBuffer = malloc(sizeof(char)* boot ->BPB_BytsPerSec * boot->BPB_SecPerClus);
	traerCluster(boot, primerSector, clusterBuffer);

	/*int i;*/
	/*	impresion del buffer obtenido	*/
	/*printf("\n");
	for(i=0; i<4096; i++)
		{
		printf("%02x ",clusterBuffer[i]);
		if(i%32 == 0 && i!=0)
			printf("\n");
		}
	printf("\n");*/

	int32_t* posicion = malloc(sizeof(int32_t));

	int32_t res = obtenerDosPosicionesLibres(boot, cluster, clusterBuffer, posicion);

	/*	pido la posicion, si la funcion devuelve otro valor distinto de
	 * 	0 / -1, tengo que pedir el cluster correspondiente	*/
	if(res!=0 && res!= -1)
		{
		primerSector = firstSectorofCluster(boot, res);
		/*	pido el nuevo cluster	*/
		traerCluster(boot, primerSector, clusterBuffer);
		}
	if(res == -1)
		{
		escribir_logfile(NOMPS, 0, ERROR, "No se encontraron dos posiciones libres para crear entradas dentro del cluster...");
		return -1;
		}

	ponerEnClusterLFN(clusterBuffer, lfn, *posicion);

	*posicion +=32;

	ponerEnClusterDir(clusterBuffer,  dir, *posicion);

	persistirCluster(boot, cluster, clusterBuffer);

	free(posicion);
	free(clusterBuffer);
	return 0;
}

int32_t crearEntradaDOT_DOTDOT(struct bootSector* boot, uint32_t cluster, uint32_t parentCluster)
{

	/*	son las dos primeras entradas de cualquier directorio, SIEMPRE	*/

	struct DirStruct* dirDOT = malloc(sizeof(struct DirStruct));
	struct DirStruct* dirDOTDOT = malloc(sizeof(struct DirStruct));

	llenarDOT_DOTDOT(dirDOT, dirDOTDOT);

	/*	clusters direccion	*/
	unsigned char* bufferDOT = malloc(sizeof(char)*4);
	ponerHexaEnBuffer(swap_uint32(cluster), bufferDOT);
	unsigned char* bufferDOTDOT = malloc(sizeof(char)*4);
	ponerHexaEnBuffer(swap_uint32(parentCluster), bufferDOTDOT);

	/*	manganeta	*/
	dirDOT -> DIR_FstClusHI[0] = bufferDOT[2];
	dirDOT -> DIR_FstClusHI[1] = bufferDOT[3];
	dirDOT -> DIR_FstClusLO[0] = bufferDOT[0];
	dirDOT -> DIR_FstClusLO[1] = bufferDOT[1];

	dirDOTDOT -> DIR_FstClusHI[0] = bufferDOTDOT[2];
	dirDOTDOT -> DIR_FstClusHI[1] = bufferDOTDOT[3];
	dirDOTDOT -> DIR_FstClusLO[0] = bufferDOTDOT[0];
	dirDOTDOT -> DIR_FstClusLO[1] = bufferDOTDOT[1];

	int32_t primerSector = firstSectorofCluster(boot, cluster);
	/*	pido el cluster en base al primer sector	*/
	unsigned char* clusterBuffer = malloc(sizeof(char)* boot ->BPB_BytsPerSec * boot->BPB_SecPerClus);
	traerCluster(boot, primerSector, clusterBuffer);

	ponerEnClusterDir(clusterBuffer,  dirDOT, 0);

	ponerEnClusterDir(clusterBuffer,  dirDOTDOT, 32);

	persistirCluster(boot, cluster, clusterBuffer);

	free(bufferDOT);
	free(bufferDOTDOT);
	free(dirDOT);
	free(dirDOTDOT);
	free(clusterBuffer);
	return 0;
}

int32_t llenarDOT_DOTDOT(struct DirStruct* dot, struct DirStruct* dotdot)
{

	int32_t i;
	for(i=0; i<11; i++)
		{
		dot -> DIR_Name[i] = ESPACIO_SHORT_NAME;
		dotdot -> DIR_Name[i] = ESPACIO_SHORT_NAME;
		}

	/*	NAME	*/
	dot -> DIR_Name[0] = DOT_DotDot;

	dotdot -> DIR_Name[0] = DOT_DotDot;
	dotdot -> DIR_Name[1] = DOT_DotDot;

	/*	atributo	*/
	dot -> DIR_Attr = ATTR_DIRECTORY;

	dotdot -> DIR_Attr = ATTR_DIRECTORY;

	/*	size	*/
	dot -> DIR_FileSizePOSTA[0] = 0x00;
	dot -> DIR_FileSizePOSTA[1] = 0x00;
	dot -> DIR_FileSizePOSTA[2] = 0x00;
	dot -> DIR_FileSizePOSTA[3] = 0x00;

	dotdot -> DIR_FileSizePOSTA[0] = 0x00;
	dotdot -> DIR_FileSizePOSTA[1] = 0x00;
	dotdot -> DIR_FileSizePOSTA[2] = 0x00;
	dotdot -> DIR_FileSizePOSTA[3] = 0x00;

	return 0;
}

int32_t modificarDir(struct bootSector* boot, ListaDirectorios* ldir, struct LongDirStruct* lfn)
{

	int32_t primerSector = firstSectorofCluster(boot, ldir -> parentCluster);
	/*	pido el cluster en base al primer sector	*/
	unsigned char* clusterBuffer = malloc(sizeof(char)* boot ->BPB_BytsPerSec * boot->BPB_SecPerClus);
	traerCluster(boot, primerSector, clusterBuffer);

	ponerEnClusterDir(clusterBuffer, ldir -> directorio, ldir -> posicionEntrada);

	/*	por rename	*/
	if(lfn != NULL)
		{
		/*tengo que generar una nueva lfn*/
		int32_t posicionLFN = ldir -> posicionEntrada - LARGO_STRUCT_DIRECTORY;
		ponerEnClusterLFN(clusterBuffer, lfn, posicionLFN);
		}

	persistirCluster(boot, ldir -> parentCluster , clusterBuffer);

	free(clusterBuffer);
	return 0;
}

/*	Si es el mismo cluster, devuelve cero, y en posicion deja el offset.
 * 	si tengo que pedir otro cluster, devuelve el cluster final y su offset
 * 	-1 por error	*/
int32_t obtenerDosPosicionesLibres(struct bootSector* boot, uint32_t cluster, unsigned char* clusterBuffer, int32_t* posicion)
{

	int32_t max = boot ->BPB_BytsPerSec * boot ->BPB_SecPerClus;
	int32_t i = 0;

	while(1)
		{

		if((clusterBuffer[i] == DIR_Name_POWER_FREE)  &&  (i<=(max-LARGO_STRUCT_DIRECTORY-1)))
			{
			*posicion = i;
			break;
			}

		/*	si la entrada esta libre, no estoy al borde de terminar el cluster, y la proxima entrada esta libre	*/
		else if(clusterBuffer[i] == DIR_Name_FREE && (i<=(max-32-1))
					&& (clusterBuffer[i+32] == DIR_Name_FREE || clusterBuffer[i+32] == DIR_Name_POWER_FREE) )
				{
				*posicion = i;
				break;
				}

		i+=32;
		if(i>=max)
			{
			uint32_t proxCluster;
			if(verificarUltimoClusterCadena(boot, cluster) == 0)
				{
				/*	cluster lleno	*/
				/*	pido cluster libre	*/
				proxCluster = dameClusterLibre(boot);
				if(proxCluster != -1)
					{
					/*	modifico entrada FAT	*/
					pthread_mutex_lock(&mutex_fat);
					cambiarEntradaFAT(boot, cluster, proxCluster);
					pthread_mutex_unlock(&mutex_fat);
					/*	persistir fat	*/
					persistirFAT(boot);
					}
				else
					return -1;
				}
			else
				{
				/*	continuo explorando el siguiente cluster	*/
				proxCluster =  leerEntradaFAT(boot, cluster);
				}

			int32_t primerSector = firstSectorofCluster(boot, proxCluster);
			/*	pido el nuevo cluster	*/
			traerCluster(boot, primerSector, clusterBuffer);
			i=0;
			}
		}

	return 0;
}

int32_t borrarEntradaCluster(struct bootSector* boot, ListaDirectorios* ldir)
{

	int32_t cluster = ldir -> parentCluster;
	int32_t primerSector = firstSectorofCluster(boot, cluster);
	/*	pido el cluster en base al primer sector	*/
	unsigned char* clusterBuffer = malloc(sizeof(char)* boot ->BPB_BytsPerSec * boot->BPB_SecPerClus);
	traerCluster(boot, primerSector, clusterBuffer);

	int32_t posicionLFN = ldir -> posicionEntrada - 32;
	if(posicionLFN < 0)
		{
		/*	algo esta mal	*/
		/*	LOG	*/
		return -1;
		}

	/*	Si no tengo LFN no tengo que borrar la entrada anterior	*/
	if(ldir ->nombreLargo != NULL)
		clusterBuffer[posicionLFN] = DIR_Name_FREE;

	clusterBuffer[ldir-> posicionEntrada] = DIR_Name_FREE;

	/*int i;*/
	/*	impresion del buffer obtenido	*/
	/*printf("\n");
	for(i=0; i<4096; i++)
		{
		printf("%02x ",clusterBuffer[i]);
		if(i%32 == 0 && i!=0)
			printf("\n");
		}
	printf("\n");*/

	persistirCluster(boot, cluster, clusterBuffer);

	free(clusterBuffer);
	return 0;
}

int32_t borrarEntradaClusterDIR(struct bootSector* boot, ListaDirectorios* ldir)
{

	int32_t cluster = proximaEntryDir(ldir -> directorio);
	int32_t primerSector = firstSectorofCluster(boot, cluster);
	/*	pido el cluster en base al primer sector	*/
	unsigned char* clusterBuffer = malloc(sizeof(char)* boot ->BPB_BytsPerSec * boot->BPB_SecPerClus);
	traerCluster(boot, primerSector, clusterBuffer);

	//	DOT
	clusterBuffer[0] = DIR_Name_FREE;

	//	DOT DOT
	clusterBuffer[32] = DIR_Name_FREE;

	persistirCluster(boot, cluster, clusterBuffer);

	free(clusterBuffer);
	return 0;
}

int32_t cantidadClusterSegunTamanio(struct bootSector* boot, uint32_t size)
{

	int32_t tamCluster = boot -> BPB_BytsPerSec * boot -> BPB_SecPerClus;

	float resto = size % tamCluster;

	int32_t numCluster = size / tamCluster;

	if(resto != 0)
		numCluster++;

	return numCluster;
}

int32_t cantidadClusterActualDir(struct bootSector* boot, ListaDirectorios* dir)
{

	int32_t clusterAct;

	/*	los archivos recien creados se les pone cluster siguiente = 0*/
	uint32_t sigCluster = proximaEntryDir(dir ->directorio);
	if( sigCluster == 0)
		return 0;

	else
		{
		// ya tengo uno
		clusterAct = 1;

		while(1)
				{
				if(verificarUltimoClusterCadena(boot, sigCluster) == -1)
					{
					clusterAct++;
					sigCluster = leerEntradaFAT(boot, sigCluster);
					}

				else
					break;
				}
		}

	return clusterAct;
}

int32_t crearCadenaCluster(struct bootSector* boot, ListaDirectorios* dir)
{

	uint32_t contador;
	int32_t espacioClusters = dir -> directorio -> DIR_FileSize;

	//	size == 0
	if(espacioClusters == 0)
		{
		//	archivo sin nada
		dir -> clusters = malloc(sizeof(int32_t)*1);
		dir -> clusters[0] = SIGNAL_NO_MORE;
		}

	else
		{
		int32_t largoCluster = boot -> BPB_BytsPerSec * boot -> BPB_SecPerClus;
		if(espacioClusters%largoCluster != 0)
			{
			espacioClusters /= largoCluster;
			espacioClusters += 1;
			}
		else
			espacioClusters /= largoCluster;

											/*	clusters + signal	*/
		dir -> clusters = malloc(sizeof(int32_t)* (espacioClusters+1));
		uint32_t proximoCluster =  proximaEntryDir(dir -> directorio);
		dir -> clusters[0] = proximoCluster;

			for(contador=0; contador < espacioClusters; contador++)
				{
				if(verificarUltimoClusterCadena(boot, proximoCluster) == -1)
					{
					proximoCluster = leerEntradaFAT(boot, proximoCluster);
					dir -> clusters[contador+1] = proximoCluster;
					}
				}
			dir -> clusters[espacioClusters] = SIGNAL_NO_MORE;
		}

	/*int i = 0;
	while(1)
		{
		if(	dir -> clusters[i] != SIGNAL_NO_MORE)
			{printf("%i ", dir -> clusters[i]); i++;}
		else
			break;
		}
	printf("\n");*/

	return 0;

}

int32_t crearCadenaClusterLista(struct bootSector* boot, ListaDirectorios* dir, int32_t *lista)
{

	uint32_t contador;
	int32_t espacioClusters = dir -> directorio -> DIR_FileSize;

	//	size == 0
	if(espacioClusters == 0)
		return 0;
		//lista[0] = SIGNAL_NO_MORE;

	else
		{
		int32_t largoCluster = boot -> BPB_BytsPerSec * boot -> BPB_SecPerClus;
		if(espacioClusters%largoCluster != 0)
			{
			espacioClusters /= largoCluster;
			espacioClusters += 1;
			}
		else
			espacioClusters /= largoCluster;

		uint32_t proximoCluster =  proximaEntryDir(dir -> directorio);
		lista[0] = proximoCluster;

			for(contador=0; contador < espacioClusters; contador++)
				{
				if(verificarUltimoClusterCadena(boot, proximoCluster) == -1)
					{
					proximoCluster = leerEntradaFAT(boot, proximoCluster);
					lista[contador+1] = proximoCluster;
					}
				}
			//lista[espacioClusters] = SIGNAL_NO_MORE;
		}

	return 0;

}

int32_t modificarDOTDOTDir(struct bootSector* boot, uint32_t cluster, int32_t valorDOTDOT)
{

	int32_t primerSector = firstSectorofCluster(boot, cluster);
	/*	pido el cluster en base al primer sector	*/
	unsigned char* clusterBuffer = malloc(sizeof(char)* boot ->BPB_BytsPerSec * boot->BPB_SecPerClus);
	traerCluster(boot, primerSector, clusterBuffer);
	unsigned char* dotDotBuff = malloc(sizeof(char)*LARGO_STRUCT_DIRECTORY);

	/*tomo la entrada ..*/
	int32_t i;
	for(i=0; i< LARGO_STRUCT_DIRECTORY; i++)
		dotDotBuff[i]=clusterBuffer[i+32];

	struct DirStruct* dir = malloc(sizeof(struct DirStruct));
	interpretarEntradaDirectorioArchivo(dir, dotDotBuff);

	unsigned char* bufferClus = malloc(sizeof(char)*4);
	ponerHexaEnBuffer(swap_uint32(valorDOTDOT), bufferClus);
	/*	manganeta	*/
	dir -> DIR_FstClusHI[0] = bufferClus[2];
	dir -> DIR_FstClusHI[1] = bufferClus[3];
	dir -> DIR_FstClusLO[0] = bufferClus[0];
	dir -> DIR_FstClusLO[1] = bufferClus[1];
	free(bufferClus);

									/*	DOTDOT	*/
	ponerEnClusterDir(clusterBuffer, dir, 32);

	persistirCluster(boot, cluster, clusterBuffer);

	free(dir);
	free(dotDotBuff);
	free(clusterBuffer);
	return 0;
}

int32_t leerBootSector(struct bootSector* miArchivoDisco)
{
	/*	FAT32	*/
	/*	FAT32	*/
	/*	FAT32	*/

	/*	Little Endian, un numero en el disco ==> 0x0001
	 * 	se almacena de la siguiente manera 		01 00		*/

	unsigned char* bufferFile = malloc(sizeof(char)* 512 * 8);
	traerCluster(miArchivoDisco, 0, bufferFile);

	int i;

	char* aux = malloc(sizeof(char)*10);

/************************************************************
 * 						BS_jmpBoot
 ************************************************************	*/

	miArchivoDisco -> BS_jmpBoot[0]= bufferFile[0];
	miArchivoDisco -> BS_jmpBoot[1]= bufferFile[1];
	miArchivoDisco -> BS_jmpBoot[2]= bufferFile[2];

	/*for(i=0; i<3; i++)
		printf("%02x ", miArchivoDisco -> BS_jmpBoot[i]);
	printf("\n");*/

/************************************************************
 * 						BS_OEMName
 ************************************************************	*/

	for(i=3; i<11; i++)
		miArchivoDisco -> BS_OEMName[i-3]= bufferFile[i];

	miArchivoDisco -> BS_OEMName[8] = '\0';

	/*printf("Name: %s\n", miArchivoDisco -> BS_OEMName );*/

/************************************************************
 * 						BPB_BytsPerSec
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[11])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[11])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[12])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[12])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_BytsPerSec = swap_uint16(htoi(aux));

	/*printf("%i\n", miArchivoDisco -> BPB_BytsPerSec);*/

/************************************************************
 * 						BPB_SecPerClus
 ************************************************************	*/

	strcpy(aux, "0x");

	strcat(aux, hexToChar(valorHighChar(bufferFile[13])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[13])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_SecPerClus = htoi(aux);

	/*printf("%i\n", miArchivoDisco -> BPB_SecPerClus);*/

/************************************************************
 * 						BPB_RsvdSecCnt
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[14])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[14])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[15])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[15])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_RsvdSecCnt = swap_uint16(htoi(aux));
			htoi(aux);

	/*printf("%i\n", miArchivoDisco -> BPB_RsvdSecCnt);*/

/************************************************************
 * 						BPB_NumFATs
 ************************************************************	*/

	strcpy(aux, "0x");

	strcat(aux, hexToChar(valorHighChar(bufferFile[16])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[16])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_NumFATs = htoi(aux);

	/*printf("%i\n", miArchivoDisco -> BPB_NumFATs);*/

/************************************************************
 * 						BPB_RootEntCnt
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[17])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[17])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[18])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[18])));


	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_RootEntCnt = swap_uint16(htoi(aux));

	/*printf("%i\n", miArchivoDisco -> BPB_RootEntCnt);*/

/************************************************************
 * 						BPB_TotSec16
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[19])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[19])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[20])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[20])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_TotSec16 = swap_uint16(htoi(aux));

	/*printf("%i\n", miArchivoDisco -> BPB_TotSec16);*/

/************************************************************
 * 						BPB_Media
 ************************************************************	*/

	miArchivoDisco -> BPB_Media = bufferFile[21];
	/*printf("%02x\n", miArchivoDisco -> BPB_Media);*/

/************************************************************
 * 						BPB_FATSz16
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[22])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[22])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[23])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[23])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_FATSz16 = swap_uint16(htoi(aux));

	/*printf("%i\n", miArchivoDisco -> BPB_FATSz16);*/

/************************************************************
 * 						BPB_SecPerTrk
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[24])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[24])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[25])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[25])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_SecPerTrk = swap_uint16(htoi(aux));

	/*printf("%i\n", miArchivoDisco -> BPB_SecPerTrk);*/

/************************************************************
 * 						BPB_NumHeads
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[26])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[26])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[27])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[27])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_NumHeads = swap_uint16(htoi(aux));

	/*printf("%i\n", miArchivoDisco -> BPB_NumHeads);*/

/************************************************************
 * 						BPB_HiddSec
 ************************************************************	*/

	/*strcpy(aux, "0xffffffff");*/ 	/*	chequeado	*/
	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[28])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[28])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[29])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[29])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[30])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[30])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[31])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[31])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_HiddSec = swap_uint32(htoi(aux));

	/*printf("%u\n", miArchivoDisco -> BPB_HiddSec);*/

/************************************************************
 * 						BPB_TotSec32
 ************************************************************	*/

	/*strcpy(aux, "0xffffffff");*/ 	/*	chequeado	*/
	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[32])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[32])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[33])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[33])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[34])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[34])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[35])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[35])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_TotSec32 = swap_uint32(htoi(aux));

	/*printf("%u\n", miArchivoDisco -> BPB_TotSec32);*/

/*	Termino el boot sector	*/

/*************************************************************/
/*************************************************************/
/*	FAT32 Structure Starting at Offset 36	*/
/*	FAT32 Structure Starting at Offset 36	*/
/*************************************************************/
/*************************************************************/

/************************************************************
 * 						BPB_FATSz32
 ************************************************************	*/

	/*strcpy(aux, "0xffffffff");*/ 	/*	chequeado	*/
	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[36])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[36])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[37])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[37])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[38])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[38])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[39])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[39])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_FATSz32 = swap_uint32(htoi(aux));

	/*printf("%u\n", miArchivoDisco -> BPB_FATSz32);*/

/************************************************************
 * 						BPB_ExtFlags
 ************************************************************	*/

	miArchivoDisco -> BPB_ExtFlags[0] = bufferFile[40];
	miArchivoDisco -> BPB_ExtFlags[1] = bufferFile[41];

	/*for(i=0; i<2; i++)
		printf("%02x ", miArchivoDisco -> BPB_ExtFlags[i]);
	printf("\n");*/

/************************************************************
 * 						BPB_ExtFlags
 ************************************************************	*/

	miArchivoDisco -> BPB_FSVer[0] = bufferFile[42];
	miArchivoDisco -> BPB_FSVer[1] = bufferFile[43];

/*	for(i=0; i<2; i++)
		printf("%02x ", miArchivoDisco -> BPB_FSVer[i]);
	printf("\n");*/

/************************************************************
 * 						BPB_RootClus
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[44])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[44])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[45])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[45])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[46])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[46])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[47])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[47])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_RootClus = swap_uint32(htoi(aux));

	/*printf("%u\n", miArchivoDisco -> BPB_RootClus);*/

/************************************************************
 * 						BPB_FSInfo
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[48])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[48])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[49])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[49])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_FSInfo = swap_uint16(htoi(aux));

	/*printf("%u\n", miArchivoDisco -> BPB_FSInfo);*/

/************************************************************
 * 						BPB_BkBootSec
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[50])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[50])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[51])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[51])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BPB_BkBootSec = swap_uint16(htoi(aux));

	/*printf("%u\n", miArchivoDisco -> BPB_BkBootSec);*/

/************************************************************
 * 						BPB_Reserved
 ************************************************************	*/

	miArchivoDisco -> BPB_Reserved[0] = bufferFile[52];
	miArchivoDisco -> BPB_Reserved[1] = bufferFile[53];
	miArchivoDisco -> BPB_Reserved[2] = bufferFile[54];
	miArchivoDisco -> BPB_Reserved[3] = bufferFile[55];
	miArchivoDisco -> BPB_Reserved[4] = bufferFile[56];
	miArchivoDisco -> BPB_Reserved[5] = bufferFile[57];
	miArchivoDisco -> BPB_Reserved[6] = bufferFile[58];
	miArchivoDisco -> BPB_Reserved[7] = bufferFile[59];
	miArchivoDisco -> BPB_Reserved[8] = bufferFile[60];
	miArchivoDisco -> BPB_Reserved[9] = bufferFile[61];
	miArchivoDisco -> BPB_Reserved[10] = bufferFile[62];
	miArchivoDisco -> BPB_Reserved[11] = bufferFile[63];

	/*for(i=0; i<12; i++)
		printf("%02x ", miArchivoDisco -> BPB_Reserved[i]);
	printf("\n");*/

/************************************************************
 * 						BS_DrvNum
 ************************************************************	*/

	miArchivoDisco -> BS_DrvNum[0] = bufferFile[64];

	/*printf("%02x \n", miArchivoDisco -> BPB_Reserved[i]);*/

/************************************************************
 * 						BS_Reserved1
 ************************************************************	*/

	miArchivoDisco -> BS_Reserved1[0] = bufferFile[65];

	/*printf("%02x \n", miArchivoDisco -> BS_Reserved1[i]);*/

/************************************************************
 * 						BS_BootSig
 ************************************************************	*/

	miArchivoDisco -> BS_Reserved1[0] = bufferFile[66];

	/*printf("%02x \n", miArchivoDisco -> BS_Reserved1[i]);*/

/************************************************************
 * 						BS_VolID
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(bufferFile[67])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[67])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[68])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[68])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[69])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[69])));
	strcat(aux, hexToChar(valorHighChar(bufferFile[70])));
	strcat(aux, hexToChar(valorLowChar(bufferFile[70])));

	/*printf("%s\n", aux);*/
	miArchivoDisco -> BS_VolID = swap_uint32(htoi(aux));

	/*printf("%u\n", miArchivoDisco -> BS_VolID);*/

/************************************************************
 * 						BS_VolLab
 ************************************************************	*/

	miArchivoDisco -> BS_VolLab[0] = bufferFile[71];
	miArchivoDisco -> BS_VolLab[1] = bufferFile[72];
	miArchivoDisco -> BS_VolLab[2] = bufferFile[73];
	miArchivoDisco -> BS_VolLab[3] = bufferFile[74];
	miArchivoDisco -> BS_VolLab[4] = bufferFile[75];
	miArchivoDisco -> BS_VolLab[5] = bufferFile[76];
	miArchivoDisco -> BS_VolLab[6] = bufferFile[77];
	miArchivoDisco -> BS_VolLab[7] = bufferFile[78];
	miArchivoDisco -> BS_VolLab[8] = bufferFile[79];
	miArchivoDisco -> BS_VolLab[9] = bufferFile[80];
	miArchivoDisco -> BS_VolLab[10] = bufferFile[81];

	miArchivoDisco -> BS_VolLab[11] = '\0';

	/*printf("%s\n", miArchivoDisco -> BS_VolLab);*/

/************************************************************
 * 						BS_FilSysType
 ************************************************************	*/

	miArchivoDisco -> BS_FilSysType[0] = bufferFile[82];
	miArchivoDisco -> BS_FilSysType[1] = bufferFile[83];
	miArchivoDisco -> BS_FilSysType[2] = bufferFile[84];
	miArchivoDisco -> BS_FilSysType[3] = bufferFile[85];
	miArchivoDisco -> BS_FilSysType[4] = bufferFile[86];
	miArchivoDisco -> BS_FilSysType[5] = bufferFile[87];
	miArchivoDisco -> BS_FilSysType[6] = bufferFile[88];
	miArchivoDisco -> BS_FilSysType[7] = bufferFile[89];

	miArchivoDisco -> BS_FilSysType[8] = '\0';

	/*printf("%s\n", miArchivoDisco -> BS_FilSysType);*/

/*************************************************************/
/*************************************************************/

	free(aux);

/*	it must be true that sector[510] equals 0x55,
 * 	and sector[511] equals 0xAA.
 */
	if(bufferFile[510] != 0x55 && bufferFile[511] != 0xAA)
		{free(bufferFile);return -1;}

	free(bufferFile);
	return 0;

}

int32_t leerFileSystemInfo(uint16_t sector, struct FSInfo* fsInfo, struct bootSector* boot)
{
	/*	FAT32 FSInfo Sector Structure */
	/*	FAT32 FSInfo Sector Structure */
	/*	FAT32 FSInfo Sector Structure */

	unsigned char* fatRegion = malloc(sizeof(char) * boot ->BPB_BytsPerSec * boot->BPB_SecPerClus);
	traerCluster(boot, sector, fatRegion);

	int i;

	char* aux = malloc (sizeof(char)*20);

/************************************************************
 * 						FSI_LeadSig
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(fatRegion[0])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[0])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[1])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[1])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[2])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[2])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[3])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[3])));

	/*printf("%s\n", aux);*/
	fsInfo -> FSI_LeadSig = swap_uint32(htoi(aux));

	/*printf("%u\n", fsInfo -> FSI_LeadSig);*/

	if(fsInfo -> FSI_LeadSig != FSI_LEAD_SIG)
		/*	Value 0x41615252. This lead signature is used to validate
		 * 	that this is in fact an FSInfo sector.
		 */
		return -1;

/************************************************************
 * 						FSI_Reserved1[480]
 ************************************************************	*/

	for(i=0; i<480; i++)
		fsInfo -> FSI_Reserved1[0] = fatRegion[i+4];

	/*for(i=0; i<480; i++)
		printf("%02x ",fsInfo -> FSI_Reserved1[i]);
	printf("\n");*/


/************************************************************
 * 						FSI_StrucSig
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(fatRegion[484])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[484])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[485])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[485])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[486])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[486])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[487])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[487])));

	/*printf("%s\n", aux);*/
	fsInfo -> FSI_StrucSig = swap_uint32(htoi(aux));

	/*printf("%u\n", fsInfo -> FSI_StrucSig);*/

	if(fsInfo -> FSI_StrucSig != FSI_STRUCS_SIG)
		/*	Value 0x61417272. Another signature that is more localized
		 * 	in the sector to the location of the fields that are used.
		 */
		return -1;

/************************************************************
 * 						FSI_Free_Count
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(fatRegion[488])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[488])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[489])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[489])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[490])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[490])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[491])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[491])));

	/*printf("%s\n", aux);*/
	fsInfo -> FSI_Free_Count = swap_uint32(htoi(aux));

	/*printf("%u\n", fsInfo -> FSI_Free_Count);*/

/************************************************************
 * 						FSI_Nxt_Free
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(fatRegion[492])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[492])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[493])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[493])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[494])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[494])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[495])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[495])));

	/*printf("%s\n", aux);*/
	fsInfo -> FSI_Nxt_Free = swap_uint32(htoi(aux));

	/*printf("%u\n", fsInfo -> FSI_Nxt_Free);*/

/************************************************************
 * 						FSI_Reserved2
 ************************************************************	*/

	for(i=0; i<12; i++)
		fsInfo -> FSI_Reserved2[0] = fatRegion[i+496];

/*	for(i=0; i<12; i++)
		printf("%02x ",fsInfo -> FSI_Reserved2[i]);
	printf("\n");*/

/************************************************************
 * 						FSI_TrailSig
 ************************************************************	*/

	strcpy(aux, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(aux, hexToChar(valorHighChar(fatRegion[508])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[508])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[509])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[509])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[510])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[510])));
	strcat(aux, hexToChar(valorHighChar(fatRegion[511])));
	strcat(aux, hexToChar(valorLowChar(fatRegion[511])));

	/*printf("%s\n", aux);*/
	fsInfo -> FSI_TrailSig = swap_uint32(htoi(aux));

	/*printf("%u\n", fsInfo -> FSI_TrailSig);*/


	free(aux);

	if(fsInfo -> FSI_TrailSig != FSI_TRAIL_SIG)
		/*	Value 0xAA550000. This trail signature is used to validate
		 * 	that this is in fact an FSInfo sector.
		 */
		{free(fatRegion);return -1;}

	free(fatRegion);
	return 0;

}

uint32_t interpretarEntradaDirectorioArchivo(struct DirStruct* directorio, unsigned char* bufferStruct)
{

	uint32_t i;

/**************************	DIR_Name *****************************/

	for(i=0; i<11; i++)
		directorio -> DIR_Name[i] = bufferStruct[i];

	/*directorio -> DIR_Name[12] = '\0';*/

/**************************	DIR_Attr *****************************/

	directorio -> DIR_Attr = bufferStruct[11];

/**************************	DIR_NTRes ****************************/

	directorio -> DIR_NTRes = bufferStruct[12];

/**********************	DIR_CrtTimeTenth *************************/

	directorio -> DIR_CrtTimeTenth = bufferStruct[13];

/**************************	DIR_CrtTime **************************/

	directorio -> DIR_CrtTime[0] = bufferStruct[14];
	directorio -> DIR_CrtTime[1] = bufferStruct[15];

/**************************	DIR_CrtDate **************************/

	directorio -> DIR_CrtDate[0] = bufferStruct[16];
	directorio -> DIR_CrtDate[1] = bufferStruct[17];

/**********************	DIR_LstAccDate ***************************/

	directorio -> DIR_LstAccDate[0] = bufferStruct[18];
	directorio -> DIR_LstAccDate[1] = bufferStruct[19];

/**********************	DIR_FstClusHI ****************************/

	directorio -> DIR_FstClusHI[0] = bufferStruct[20];
	directorio -> DIR_FstClusHI[1] = bufferStruct[21];

/**********************	DIR_WrtTime ******************************/

	directorio -> DIR_WrtTime[0] = bufferStruct[22];
	directorio -> DIR_WrtTime[1] = bufferStruct[23];

/**********************	DIR_WrtDate ******************************/

	directorio -> DIR_WrtDate[0] = bufferStruct[24];
	directorio -> DIR_WrtDate[1] = bufferStruct[25];

/**********************	DIR_FstClusLO ****************************/

	directorio -> DIR_FstClusLO[0] = bufferStruct[26];
	directorio -> DIR_FstClusLO[1] = bufferStruct[27];

/**********************	DIR_FileSize *****************************/

	char* auxChar = malloc (sizeof(char) * 20);
	strcpy(auxChar, "0x");

	/*	guarda, esta al revez, Little Endian	*/
	strcat(auxChar, hexToChar(valorHighChar(bufferStruct[28])));
	strcat(auxChar, hexToChar(valorLowChar(bufferStruct[28])));
	strcat(auxChar, hexToChar(valorHighChar(bufferStruct[29])));
	strcat(auxChar, hexToChar(valorLowChar(bufferStruct[29])));
	strcat(auxChar, hexToChar(valorHighChar(bufferStruct[30])));
	strcat(auxChar, hexToChar(valorLowChar(bufferStruct[30])));
	strcat(auxChar, hexToChar(valorHighChar(bufferStruct[31])));
	strcat(auxChar, hexToChar(valorLowChar(bufferStruct[31])));

	/*printf("%s\n", auxChar);*/
	directorio -> DIR_FileSize = swap_uint32(htoi(auxChar));

	directorio -> DIR_FileSizePOSTA[0] = bufferStruct[28];
	directorio -> DIR_FileSizePOSTA[1] = bufferStruct[29];
	directorio -> DIR_FileSizePOSTA[2] = bufferStruct[30];
	directorio -> DIR_FileSizePOSTA[3] = bufferStruct[31];

/*****************************************************************/

	free(auxChar);
	return 0;
}

uint32_t interpretarEntradaLFN(struct LongDirStruct* longDir, unsigned char* bufferStruct)
{

	uint32_t i;

/**************************	LDIR_Ord *****************************/

	longDir -> LDIR_Ord = bufferStruct[0];

/*************************	LDIR_Name1 ***************************/

	for(i=0; i<10; i++)
		longDir -> LDIR_Name1[i] = bufferStruct[1+i];

/*************************	LDIR_Attr ****************************/

	longDir -> LDIR_Attr = bufferStruct[11];

/*************************  LDIR_Type  ***************************/

	longDir -> LDIR_Type = bufferStruct[12];

/*************************  LDIR_Chksum  *************************/

	longDir -> LDIR_Chksum = bufferStruct[13];

/*************************  LDIR_Name2  **************************/

	for(i=0; i<12; i++)
		longDir -> LDIR_Name2[i] = bufferStruct[14+i];

/***********************  LDIR_FstClusLO  ************************/

	longDir -> LDIR_FstClusLO[0] = bufferStruct[26];
	longDir -> LDIR_FstClusLO[1] = bufferStruct[27];

/*************************  LDIR_Name3  **************************/

	for(i=0; i<4; i++)
		longDir -> LDIR_Name3[i] = bufferStruct[28+i];

/*****************************************************************/

	return 0;

}


int32_t ponerEnClusterDir(unsigned char* cluster, struct DirStruct* dir, int32_t posicion)
{

	int32_t i;

/**************************	DIR_Name *****************************/

	for(i=0; i<11; i++)
		cluster[posicion+i] = dir -> DIR_Name[i];

/**************************	DIR_Attr *****************************/

	posicion += 11;
	cluster[posicion] = dir -> DIR_Attr;

/**************************	DIR_NTRes ****************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_NTRes;

/**********************	DIR_CrtTimeTenth *************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_CrtTimeTenth;

/**************************	DIR_CrtTime **************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_CrtTime[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_CrtTime[1];

/**************************	DIR_CrtDate **************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_CrtDate[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_CrtDate[1];

/**********************	DIR_LstAccDate ***************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_LstAccDate[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_LstAccDate[1];

/**********************	DIR_FstClusHI ****************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_FstClusHI[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_FstClusHI[1];

/**********************	DIR_WrtTime ******************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_WrtTime[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_WrtTime[1];

/**********************	DIR_WrtDate ******************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_WrtDate[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_WrtDate[1];

/**********************	DIR_FstClusLO ****************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_FstClusLO[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_FstClusLO[1];

/**********************	DIR_FileSize *****************************/

	posicion ++;
	cluster[posicion] = dir -> DIR_FileSizePOSTA[0];
	posicion ++;
	cluster[posicion] = dir -> DIR_FileSizePOSTA[1];
	posicion ++;
	cluster[posicion] = dir -> DIR_FileSizePOSTA[2];
	posicion ++;
	cluster[posicion] = dir -> DIR_FileSizePOSTA[3];

	/*	impresion del buffer obtenido	*/
	/*printf("\n");
	for(i=0; i<4096; i++)
		{
		printf("%02x ",cluster[i]);
		if(i%32 == 0 && i!=0)
			printf("\n");
		}
	printf("\n");*/

	return 0;
}

int32_t ponerEnClusterLFN(unsigned char* cluster, struct LongDirStruct* lfn, int32_t posicion)
{

	uint32_t i;

/**************************	LDIR_Ord *****************************/

	 cluster[posicion] = lfn -> LDIR_Ord;

/*************************	LDIR_Name1 ***************************/

	posicion ++;
	for(i=0; i<10; i++)
		cluster[posicion+i] = lfn -> LDIR_Name1[i];

/*************************	LDIR_Attr ****************************/

	posicion += 10;
	cluster[posicion] = lfn -> LDIR_Attr;

/*************************  LDIR_Type  ***************************/

	posicion ++;
	cluster[posicion] = lfn -> LDIR_Type;

/*************************  LDIR_Chksum  *************************/

	posicion ++;
	cluster[posicion] = lfn -> LDIR_Chksum;

/*************************  LDIR_Name2  **************************/

	posicion ++;
	for(i=0; i<12; i++)
		cluster[posicion+i] = lfn -> LDIR_Name2[i];

/***********************  LDIR_FstClusLO  ************************/

	posicion +=12;
	cluster[posicion] = lfn -> LDIR_FstClusLO[0];
	posicion ++;
	cluster[posicion] = lfn -> LDIR_FstClusLO[1];

/*************************  LDIR_Name3  **************************/

	posicion++;
	for(i=0; i<4; i++)
		cluster[posicion+i] = lfn -> LDIR_Name3[i];

/*****************************************************************/

	/*	impresion del buffer obtenido	*/
	/*printf("\n");
	for(i=0; i<4096; i++)
		{
		printf("%02x ",cluster[i]);
		if(i%32 == 0 && i!=0)
			printf("\n");
		}
	printf("\n");*/

	return 0;

}

uint64_t htoi(char s[])
{
	uint64_t val = 0;
    int x = 0;

    if(s[x] == '0' && (s[x+1]=='x' || s[x+1]=='X')) x+=2;

    while(s[x]!='\0')
    {
       if(val > UINT_MAX) return 0;
       else if(s[x] >= '0' && s[x] <='9')
       {
          val = val * 16 + s[x] - '0';
       }
       else if(s[x]>='A' && s[x] <='F')
       {
          val = val * 16 + s[x] - 'A' + 10;
       }
       else if(s[x]>='a' && s[x] <='f')
       {
          val = val * 16 + s[x] - 'a' + 10;
       }
       else return 0;

       x++;
    }
    return val;
}


/*
*	To convert 53 to the character 'S':
*	char returnVal = hexToString('5', '3');
*/
char hexToAscii(char first, char second)
{
	char hex[5], *stop;
	hex[0] = '0';
	hex[1] = 'x';
	hex[2] = first;
	hex[3] = second;
	hex[4] = 0;
	return strtol(hex, &stop, 16);
}


char* hexToChar(int numero)
{
	switch(numero)
		{
		case 0: return "0";
		case 1: return "1";
		case 2: return "2";
		case 3: return "3";
		case 4: return "4";
		case 5: return "5";
		case 6: return "6";
		case 7: return "7";
		case 8: return "8";
		case 9: return "9";
		case 0xa: return "A";
		case 0xb: return "B";
		case 0xc: return "C";
		case 0xd: return "D";
		case 0xe: return "E";
		case 0xf: return "F";
		default: return NULL;
		}
}

char hexToChar2(int numero)
{
	switch(numero)
		{
		case 0: return '0';
		case 1: return '1';
		case 2: return '2';
		case 3: return '3';
		case 4: return '4';
		case 5: return '5';
		case 6: return '6';
		case 7: return '7';
		case 8: return '8';
		case 9: return '9';
		case 0xa: return 'A';
		case 0xb: return 'B';
		case 0xc: return 'C';
		case 0xd: return 'D';
		case 0xe: return 'E';
		case 0xf: return 'F';
		default: return 0;
		}
}

int valorHighChar(char valor)
{
	int resultado = 0;

	if(valor & 0x10)
		resultado += 1;

	if(valor & 0x20)
		resultado += 2;

	if(valor & 0x40)
		resultado += 4;

	if(valor & 0x80)
		resultado += 8;

	return resultado;
}

int valorLowChar(char valor)
{
	int resultado = 0;

	if(valor & 0x1)
		resultado += 1;

	if(valor & 0x2)
		resultado += 2;

	if(valor & 0x4)
		resultado += 4;

	if(valor & 0x8)
		resultado += 8;

	return resultado;
}
